<?php

namespace addons\groupon\model\store;

//use addons\groupon\model\ActivityGroupon;
use addons\groupon\model\Config;
use addons\groupon\model\Goods;
use addons\groupon\model\GoodsSkuPrice;
use addons\groupon\model\UserStore;
use app\admin\model\groupon\store\Upkeeplog;
use think\Model;
use addons\groupon\exception\Exception;
use addons\groupon\library\traits\model\order\OrderScope;
use think\Db;
use think\Queue;
use traits\model\SoftDelete;
use addons\groupon\library\traits\model\order\OrderOper;
use addons\groupon\library\traits\model\order\OrderStatus;
use addons\groupon\model\Order as BaseOrder;
use addons\groupon\model\OrderItem;
use addons\groupon\model\Store;
use addons\groupon\model\User;
use addons\groupon\model\Verify;

/**
 * 商户订单模型
 */
class Order extends BaseOrder
{
    // 
    protected $append = [
        'status_code',
        'status_name',
        'ext_arr'
    ];


    /**
     * 获取订单列表(已付款的),覆盖点 baseOrder 中 orderOper getList 方法
     */
    public static function getList($params)
    {
        $user  = User::info();
        $store = Store::info();

        // 查询分页列表
        $orders = self::buildQueryList($params)->paginate(10);

        // 查询搜索条件下的总金额
        $total_money = self::buildQueryList($params)->sum('pay_fee');

        $result = [
            'total_num'   => $orders->total(),
            'total_money' => $total_money,
            'result'      => $orders
        ];

        return $result;
    }


    /**
     * 要单独查询总金额
     */
    private static function buildQueryList($params)
    {
        $store = Store::info();

        $date_type = $params['date_type'] ?? 'today';
        $date      = $params['date'] ?? [];
        $type      = $params['type'] ?? 'all';

        // 只查付款的订单, 所有 item 都是同一个自提点的，所以 直接在这里加自提点条件
        $order = (new self())->with('item')->payed()->where('store_id', $store['id']);

        switch ($type) {
            case 'all':
                break;
            case 'nosend':
                $order = $order->nosend(false);
                break;
            case 'noarrive':
                $order = $order->noarrive();
                break;
            case 'noget':
                $order = $order->noget(true);
                break;
            case 'finish':
                $order = $order->storeFinish();
                break;
        }

        switch ($date_type) {
            case 'today':
                $start = strtotime(date('Y-m-d'));
                $end   = strtotime(date('Y-m-d', (time() + 86400)));
                break;
            case 'yesterday':
                $start = strtotime(date('Y-m-d', (time() - 86400)));
                $end   = strtotime(date('Y-m-d'));
                break;
            case 'week':
                // $start = strtotime(date('Y-m-d', (time() - (86400 * 6))));  // 减 6 天
                $start = strtotime(date('Y-m-d', strtotime("-1 week Monday")));     // 周一开始
                $end   = strtotime(date('Y-m-d', (time() + 86400)));                // 到今天结束
                break;
            case 'month':
                // $start = strtotime(date('Y-m-d', (time() - (86400 * 30))));  // 减 30 天
                $start = strtotime(date('Y-m-d', mktime(0, 0, 0, date("m"), 1, date("Y"))));  // 减 30 天
                $end   = strtotime(date('Y-m-d', (time() + 86400)));                          // 到今天结束
                break;
            case 'custom':
                $date_start = $date[0] ?? date('Y-m-d');          // 默认查 today
                $date_end   = $data[1] ?? date('Y-m-d');          // 默认查 today
                $start      = strtotime($date_start);
                $end        = strtotime($date_end) + 86400;
                break;
            default:
                $start = strtotime(date('Y-m-d'));
                $end   = strtotime(date('Y-m-d', (time() + 86400)));
                break;
        }

        $order = $order->where('createtime', '>=', $start)
            ->where('createtime', '<', $end)
            ->order('id', 'desc');

        return $order;
    }


    /**
     * 订单详情     覆盖点 baseOrder 中 orderOper detail 方法
     */
    public static function detail($params)
    {
        $user  = User::info();
        $store = Store::info();
        extract($params);

        $order = (new self())->with('item')->payed()->where('store_id', $store['id']);

        if (isset($order_sn)) {
            $order = $order->where('order_sn', $order_sn);
        }
        if (isset($id)) {
            $order = $order->where('id', $id);
        }

        $order = $order->find();

        if (!$order) {
            new Exception('订单不存在');
        }

        return $order;
    }


    /**
     * 商家核销订单, 覆盖点 baseOrder 中 orderOper operConfirm 方法
     */
    public static function operConfirm($params)
    {
        $user  = User::info();
        $store = Store::info();
        extract($params);
        $id    = $params['id'] ?? 0;
        $codes = $params['codes'] ?? [];
        try {
            Db::transaction(function () use ($store, $codes, $user) {
                // 查询核销码
                $verifies = Verify::canUse()->with(['order', 'orderItem'])->where('type', 'verify')
                    ->where('code', 'in', $codes)->lock(true)->select();

                if (!$verifies) {
                    new Exception('核销码不可用');
                }

                $check_num = 0;
                foreach ($verifies as $key => $verify) {
                    $order     = $verify['order'];
                    $orderItem = $verify['orderItem'];

                    if (!$order || $order['status'] <= 0) {
                        new Exception('订单不存在');
                    }

                    if (!$orderItem || $orderItem['store_id'] != $store['id']) {
                        new Exception('您不能操作该核销码');
                    }

                    if (!in_array($orderItem['dispatch_status'],
                        [OrderItem::DISPATCH_STATUS_READY, OrderItem::DISPATCH_STATUS_ARRIVE])) {
                        new Exception('当前商品已核销');
                    }

                    if (in_array($orderItem['refund_status'],
                        [OrderItem::REFUND_STATUS_OK, OrderItem::REFUND_STATUS_FINISH])) {
                        new Exception('当前商品已退款');
                    }

                    $check_num++;
                    $maintenance_count = $order['maintenance_count'] - 1;
                    if ($maintenance_count <= 0) {
                        $order->verifyGeted($order, $orderItem, $verify, ['oper_type' => 'store']);
                    } else {
                        \addons\groupon\model\Order::where(['id' => $order['id']])->update(['maintenance_count' => $maintenance_count]);
                    }
                    $upkeepModel    = new Upkeeplog();
                    $salesperson_id = $user->salesperson_id;
                    if (!$salesperson_id) {
                        $userStoreInfo  = UserStore::with(['user'])->where(['store_id' => $store['id']])->find();
                        $salesperson_id = $userStoreInfo->user->salesperson_id;
                    }
                    $config       = json_decode(Config::where(['name' => 'user'])->value('value'), true);
                    $store_take   = GoodsSkuPrice::where(['id' => $orderItem['goods_sku_price_id']])->value('store_take');
                    $storeTakeArr = json_decode($store_take, true);
                    if ($storeTakeArr) {
                        if ($storeTakeArr['take_type'] == 'money') {
                            $labor_cost = $storeTakeArr['take_money'];
                        } else {
                            $bili       = $storeTakeArr['take_rate'] / 100;
                            $labor_cost = bcmul($orderItem['pay_price'], $bili, 2);
                        }
                        $upkeepModel->create(
                            [
                                'user_id'           => $order['user_id'],
                                'order_id'          => $order['id'],
                                'store_id'          => $store['id'],
                                'salesperson_id'    => $salesperson_id,
                                'admin_id'          => $store['admin_id'],
                                'money'             => $labor_cost,
                                'salesperson_money' => $config['salesperson_money'],
                                'order_item_id'     => $orderItem['id']
                            ]);
                    }

                }

                if ($check_num <= 0) {
                    // 一个核销码也没核销
                    new Exception('核销失败，无效的核销码');
                }
            });
        } catch (\Exception $exception) {
            new Exception($exception->getMessage());
        }

    }


    /* -------------------------- 访问器 ------------------------ */

    /**
     * 覆盖 BaseOrder 中 OrderStatus trait getStatus 方法
     */
    protected function getStatus($data, $type)
    {
        $btns        = [];
        $status_name = '';
        $status_desc = '';

        switch ($this->status_code) {
            case 'cancel':
                $status_name = '已取消';
                break;
            case 'invalid':
                $status_name = '交易关闭';
                break;
            case 'nopay':
                $status_name = '待付款';
                break;
            // 收完货就算已完成
            case 'nocomment':
            case 'commented':
            case 'finish':
                $status_name = '已完成';
                break;
            case 'noget':
                $status_name = '待提货';
                break;
            case 'noarrive':
                $status_name = '待服务';
                break;
            case 'nosend':
                $status_name = '待备货';
                break;
            case 'refund_finish':
                $status_name = '退款完成';
                break;
            case 'refund_ing':
                $status_name = '退款处理中';
                break;
        }

        return $type == 'status_name' ? $status_name : ($type == 'btns' ? $btns : $status_desc);
    }


    /**
     * 获取支付成功之后的子状态, 自提点订单，覆盖 baseOrder model orderStatus trait 中的 getPayedStatusCode 方法
     */
    public function getPayedStatusCode($data)
    {
        $status_code = '';

        // 循环判断 item 状态
        $itemStatusCode = [];
        foreach ($this->item as $key => $item) {
            // 获取 item status
            $itemStatusCode[] = (new OrderItem)->getBaseStatusCode($item->toArray(), 'order');
        }

        // 取出不重复不为空的 status_code
        $statusCodes = array_unique(array_filter($itemStatusCode));

        if (in_array('nosend', $statusCodes)) {
            $status_code = 'nosend';
        } else {
            if (in_array('noarrive', $statusCodes)) {
                $status_code = 'noarrive';
            } else {
                if (in_array('noget', $statusCodes)) {
                    $status_code = 'noget';
                } else {
                    if (in_array('nocomment', $statusCodes)) {
                        // 存在待评价，就是待评价
                        $status_code = 'nocomment';
                    } else {
                        if (in_array('commented', $statusCodes)) {
                            // 存在已评价，就是已评价
                            $status_code = 'commented';        // 走这里，说明只评价了一部分
                        } else {
                            if (in_array('refund_finish', $statusCodes)) {
                                // 都在退款完成
                                $status_code = 'refund_finish';
                            } else {
                                if (in_array('refund_ing', $statusCodes)) {
                                    // 都在退款中
                                    $status_code = 'refund_ing';
                                }
                            }
                        }
                    }
                }
            }
        } // 售后都不在总状态显示

        return $status_code;
    }




    /* -------------------------- 模型关联 ------------------------ */

    /**
     * 关联订单 item，只查 store_id 是当前自提点的
     */
    public function item()
    {
        $store = Store::info();
        return $this->hasMany(\addons\groupon\model\OrderItem::class, 'order_id', 'id')->where('store_id',
            ($store ? $store['id'] : 0));
    }

    /**
     * 关联订单第一个 item，只查 store_id 是当前自提点的
     */
    public function firstItem()
    {
        $store = Store::info();
        return $this->hasOne(\addons\groupon\model\OrderItem::class, 'order_id', 'id')->where('store_id',
            ($store ? $store['id'] : 0));
    }
    /* -------------------------- 模型关联 ------------------------ */
}
